package org.rency.common.utils.security;

import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.rency.common.utils.enums.CharsetEnum;
import org.springframework.util.Assert;

/**
 * DES加密解密算法(对称)
 * @author: user_rcy@163.com
 * </br>Created on 2016年4月26日
 * @version: V1.0.0
 * @since JDK 1.8
 */
public class DESUtils {
	
	private final static String DES_ALGORITHM = "DES";
	    
	/**
	 * DES加密
	 * TODO
	 * </br>Created on 2016年4月26日
	 * @param data
	 * @param key 加密键byte数组
	 * @return
	 * @throws Exception
	 */
    public static String encrypt(String data, String key) throws Exception {
        byte[] bt = encrypt(data.getBytes(), key.getBytes());
        String strs = Base64Utils.encoder(bt);
        return strs;
    }
 
    /**
     * DES解密
     * </br>Created on 2016年4月26日
     * @param data
     * @param key 加密键byte数组
     * @return
     * @throws Exception
     */
    public static String decrypt(String data, String key) throws Exception {
        if (data == null){
            return null;
        }
        byte[] buf = Base64Utils.decoder(data).getBytes();
        byte[] bt = decrypt(buf,key.getBytes());
        return new String(bt);
    }
 
    /**
     * DES加密
     * </br>Created on 2016年4月26日
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    private static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        // 生成一个可信任的随机数源
        SecureRandom sr = new SecureRandom();
 
        // 从原始密钥数据创建DESKeySpec对象
        DESKeySpec dks = new DESKeySpec(key);
 
        // 创建一个密钥工厂，然后用它把DESKeySpec转换成SecretKey对象
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES_ALGORITHM);
        SecretKey securekey = keyFactory.generateSecret(dks);
 
        // Cipher对象实际完成加密操作
        Cipher cipher = Cipher.getInstance(DES_ALGORITHM);
 
        // 用密钥初始化Cipher对象
        cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
 
        return cipher.doFinal(data);
    }
          
    /**
     * DES解密
     * </br>Created on 2016年4月26日
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    private static byte[] decrypt(byte[] data, byte[] key) throws Exception {
        // 生成一个可信任的随机数源
        SecureRandom sr = new SecureRandom();
 
        // 从原始密钥数据创建DESKeySpec对象
        DESKeySpec dks = new DESKeySpec(key);
 
        // 创建一个密钥工厂，然后用它把DESKeySpec转换成SecretKey对象
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES_ALGORITHM);
        SecretKey securekey = keyFactory.generateSecret(dks);
 
        // Cipher对象实际完成解密操作
        Cipher cipher = Cipher.getInstance(DES_ALGORITHM);
 
        // 用密钥初始化Cipher对象
        cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
 
        return cipher.doFinal(data);
    }

    /**
     * 3DES加密
     * </br>Created on 2016年4月26日
     * @param originalTxt
     * @param keyTxt (长度只能为24)
     * @return
     * @throws Exception 
     */
    public static String encryptDESede(String originalTxt, String keyTxt) throws Exception {
    	Assert.isTrue(keyTxt.length() == 24, "this key size must be 24.");
        try {
            Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
            SecretKeySpec skeySpec = new SecretKeySpec(keyTxt.getBytes(CharsetEnum.UTF_8.getCode()), "DESede");
            IvParameterSpec iv = new IvParameterSpec(new byte[]{50, 51, 52, 53, 54, 55, 56, 57});
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            byte[] originalBytes = originalTxt.getBytes(CharsetEnum.UTF_8.getCode());
            byte[] encryptedBytes = cipher.doFinal(originalBytes);
            return MD5Utils.bytesToHexString(encryptedBytes);
        } catch (Exception ex) {
        	throw ex;
        }
    }

    /**
     * 3DES解密
     * </br>Created on 2016年4月26日
     * @param encryptedHexTxt
     * @param keyTxt keyTxt (长度只能为24)
     * @return
     * @throws Exception 
     */
    public static String decryptDESede(String encryptedHexTxt, String keyTxt) throws Exception {
    	Assert.isTrue(keyTxt.length() == 24, "this key size must be 24.");
        try {
            Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
            SecretKeySpec skeySpec = new SecretKeySpec(keyTxt.getBytes(CharsetEnum.UTF_8.getCode()), "DESede");
            IvParameterSpec iv = new IvParameterSpec(new byte[]{50, 51, 52, 53, 54, 55, 56, 57});
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] encryptedBytes = MD5Utils.hexStringToBytes(encryptedHexTxt);
            byte[] original = cipher.doFinal(encryptedBytes);
            return new String(original, CharsetEnum.UTF_8.getCode());
        } catch (Exception ex) {
            throw ex;
        }
    }
    
	public static void main(String[] args) throws Exception {
		System.out.println(encrypt("rency","MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDWSmemWPnhGhu5IPfnGbDPwQLpgiNGb9oQIXZ/rzWEPJ+3XUAbpLygfoKfFJ6bh7yN4QAgB9dimfcUYM6jYIA+k7H0jA3N4Eq1/w5y26cIgkTuVCUySBxj4u3CbmqhhOYiFADGsxQqqUGyhcDQV+m2tT/7DwC5BHY2kU3oWJ64fQIDAQAB"));
		System.out.println(decrypt("gNl0nOmN3S0=","MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDWSmemWPnhGhu5IPfnGbDPwQLpgiNGb9oQIXZ/rzWEPJ+3XUAbpLygfoKfFJ6bh7yN4QAgB9dimfcUYM6jYIA+k7H0jA3N4Eq1/w5y26cIgkTuVCUySBxj4u3CbmqhhOYiFADGsxQqqUGyhcDQV+m2tT/7DwC5BHY2kU3oWJ64fQIDAQAB"));
	}
	
}